package com.rockgle.reader;

import java.net.URL;
import java.util.List;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.AsyncTask;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;

import com.rockgle.persistence.DAO;
import com.rockgle.widget.PostListAdapter;

//TODO Crear otro DBContentLoader uno para cargar las siguientes 25 entradas y otro que solo meta las nuevas que no esten en el adapter
public class ContentLoader extends AsyncTask<Void, Void, Void>{
	
	private static final String BASE_URL ="http://www.blogger.com/feeds/7999164087916098920/posts/default";
	//private static final String BASE_URL ="http://www.blogger.com/feeds/3814599644188380641/posts/default";
	private SortedEntryList parsedData;
	private boolean finished;
	private PostListAdapter adapter;
	private DAO dao;
	private ProgressDialog MyDialog;
	private boolean forceDialog;
	private View view = null;
	
	public ContentLoader(PostListAdapter adapter){
		this.adapter = adapter;
		this.forceDialog = false;
	}
	
	public ContentLoader(PostListAdapter adapter, boolean forceDialog){
		this.adapter = adapter;
		this.forceDialog = forceDialog;
	}
	
	public ContentLoader(PostListAdapter adapter, View view){
		this.adapter = adapter;
		this.forceDialog = false;
		this.view = view;
	}
	
	/* (non-Javadoc)
	 * @see android.os.AsyncTask#onPreExecute()
	 */
	@Override
	protected void onPreExecute() {
		super.onPreExecute();
		dao = new DAO();
		//if (adapter!=null && dao.isEmpty()){
		if (adapter!=null && (dao.isEmpty() || this.forceDialog)){
			MyDialog = ProgressDialog.show( adapter.getContext(), "" , " Cargando entradas ... ", true);
		}
		if (adapter!=null && this.view!=null){
			Animation rotation = AnimationUtils.loadAnimation(CustomApplication.getContext(), R.anim.loading_anim);
			view.startAnimation(rotation);
		}
	}

	@Override
	protected Void doInBackground(Void... nada) {
		
		parsedData= new SortedEntryList();
		
		if (dao.isEmpty()){
			downloadAllEntries();
		}else{
			downloadNewEntries();
		}
		
		return null;
	}
	
	@Override
	protected void onPostExecute(Void result) {
		if(adapter!=null){
			new DBContentLoader(true).execute(adapter);
			adapter.notifyDataSetChanged();
			if (MyDialog!=null){
				MyDialog.dismiss();
				MyDialog=null;
			}
			if (this.view!=null){
				this.view.clearAnimation();
			}
		}else{
			if (parsedData.size() > 0){
				toolBarNotify();
			}
		}
    }
	
	private void downloadAllEntries(){
		boolean finished = false;
		StringBuilder urlbase=new StringBuilder(BASE_URL + "?max-results=300");
		StringBuilder urlstring =new StringBuilder(urlbase);
		while (!finished){
			finished = runDownload(urlstring.toString());
			urlstring =new StringBuilder(urlbase);
			
			int indexLast = parsedData.size()-1;
			if (indexLast >= 0){
				urlstring.append("&published-max=");
				Entry ultimo = parsedData.get(indexLast);
				String lastpublished = ultimo.getPublishedRFC3339();

				urlstring.append(lastpublished);
				urlstring.append("&orderby=published");
			}else{
				finished = true;
			}
		}
	}

	/**
	 * Realmente hace la descarga y el parseo
	 * @param urlstring url que va a descargar
	 * @return finished true si no se ha descargado nada nuevo
	 */
	private boolean runDownload(String urlstring){
		int startcount = parsedData.size();
		try{
			URL url = new URL(urlstring);
			
			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser sp = spf.newSAXParser();
			
			XMLReader xr = sp.getXMLReader();
			
			ExampleHandler myExampleHandler = new ExampleHandler(parsedData);
			xr.setContentHandler(myExampleHandler);
			
			xr.parse(new InputSource(url.openStream()));
			parsedData =myExampleHandler.getParsedDataList();
			parsedData = removeDoubles();
			store(parsedData);

		}catch(Exception ex){ex.printStackTrace();}
		return parsedData.size()==startcount;
	}
	
	public SortedEntryList removeDoubles(){
		SortedEntryList lista = new SortedEntryList();
		for (Entry entry : parsedData){
			if (!dao.isEntryStored(entry)){
				lista.add(entry);
			}
		}
		return lista;
	}
/*
	private boolean downloadEntries(String publishedmax) {
		StringBuilder urlstring=new StringBuilder("http://rockgle.blogspot.com/feeds/posts/default?max-results=25");
		if (!parsedData.isEmpty() || publishedmax!=null){
			urlstring.append("&published-max=");
			String lastpublished;
			if(publishedmax!=null){
				lastpublished = publishedmax;
			}else{
				int indexLast = parsedData.size()-1;
				Entry ultimo = parsedData.get(indexLast);
				lastpublished = ultimo.getPublishedRFC3339();
			}
			
			urlstring.append(lastpublished);
			urlstring.append("&orderby=published");
		}
		int startcount = parsedData.size();
		
		runDownload(urlstring.toString());
		return parsedData.size()==startcount;
	}
	*/
	
	private void downloadNewEntries(){
		StringBuilder urlbase=new StringBuilder(BASE_URL + "?max-results=300");
		StringBuilder urlstring =new StringBuilder(urlbase);
		
		List<Entry> lista = dao.getMostRecentEntries(1);
		if (lista.size()>0){
			String lastpublished = lista.get(0).getPublishedRFC3339();
			urlstring.append("&published-min=" + lastpublished);
			urlstring.append("&orderby=published");
			
			runDownload(urlstring.toString());
		}else{
			downloadAllEntries();
		}
	}
	
	public void store(SortedEntryList entries){
		for(Entry entry: entries){
			dao.addEntry(entry);
		}
	}

	/**
	 * @return the finished
	 */
	public boolean isFinished() {
		return finished;
	}

	/**
	 * @return the parsedData
	 */
	public List<Entry> getParsedData() {
		return parsedData;
	}

	/**
	 * @param parsedData the parsedData to set
	 */
	public void setParsedData(SortedEntryList parsedData) {
		this.parsedData = parsedData;
	}
	
	public void toolBarNotify(){
		String ns = Context.NOTIFICATION_SERVICE;
		Context context = CustomApplication.getContext();
		NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);
		
		int icon = R.drawable.ic_notify;
		CharSequence tickerText = "Novedades en Rockgle";
		long when = System.currentTimeMillis();

		Notification notification = new Notification(icon, tickerText, when);
		
		
		CharSequence contentTitle = "Rockgle";
		CharSequence contentText = "Hay nuevas entradas en Rockgle";
		Intent notificationIntent = new Intent(context, com.rockgle.reader.Main.class);
		PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

		notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
		
		mNotificationManager.notify(1, notification);
	}
}